import {
  CallHandler,
  ExecutionContext,
  HttpException,
  HttpStatus,
  Inject,
  Injectable,
  Logger,
  NestInterceptor,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { FastifyRequest } from 'fastify';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Observable } from 'rxjs';

@Injectable()
export class MultipartInterceptor implements NestInterceptor {
  constructor(
    @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
    private readonly configService: ConfigService,
  ) {}
  async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>> {
    const request = context.switchToHttp().getRequest<FastifyRequest>();
    const contentType = request.headers['content-type'] || '';
    const isMultipart = contentType.includes('multipart/form-data');
    if (isMultipart) {
      const file = await (request as any).file();
      // @ts-ignore
      request.multipartFile = file;
      const allowedExtensions = this.configService
        .get('UPLOAD_FILE_TYPE_LIMIT')
        ?.split(',')
        ?.filter(Boolean);
      const allowedMimeTypes = this.configService
        .get('UPLOAD_MIME_TYPE_LIMIT')
        ?.split(',')
        ?.filter(Boolean);
      const ext = file.filename?.split('.').pop()?.toLowerCase();
      if (
        (allowedMimeTypes && !allowedMimeTypes.includes(file.mimetype)) ||
        (allowedExtensions && ext && !allowedExtensions.includes(ext))
      ) {
        // 错误传递到multipart异常过滤器
        throw new HttpException('文件类型不支持', HttpStatus.BAD_REQUEST);
      }
    }
    return next.handle();
  }
}
